package dvsdk.util;

import dvsdk.client.BeanResult;
import dvsdk.client.MulisComboBoxModelUsers;
import dvsdk.client.MulisFrame;
import dvsdk.tmpl.MulisPrinter;
import dvsdk.client.MulisTable;
import dvsdk.db.Base;
import dvsdk.db.BeanBase;
import dvsdk.db.BeanParam;
import dvsdk.GlobalConfig;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Develop
 */
public class ExUtil {
    
    public static void initReTable(Base base, String name, String fields) {
        //Base base = new Base();
        base.reinit(name, fields);
        //base.disconnect();
    }

    public synchronized static BeanBase fillFromTable(Base base, String table_name, String fields, String id) {
        List<BeanBase> binBases = new ArrayList<BeanBase>();
        binBases.addAll(ExUtil.select(base, table_name, fields, "id=" + id));
        return binBases.get(0);
    }

    public synchronized static List<BeanBase> select(Base base, String base_name, String fields, String where) {
        return base.getAllElementsSync(base_name, fields, where);
    }

    public synchronized static List<BeanBase> selectSE(Base base, String base_name, String fields, String where) {
        return base.getSelElementsSync(base_name, fields, where);
    }

    public synchronized static void fillTabelData(Base base, MulisTable table, String name, String fields, boolean full) {
        fillTabelData(base, table, name, fields, "", full);
    }

    public synchronized static void fake_delete(Base base, String table_name, List<String> ids) {
        List<BeanBase> binBases = new ArrayList<BeanBase>();
        for (Iterator<String> it = ids.iterator(); it.hasNext();) {
            String string = it.next();
            BeanBase binBase = new BeanBase();
            binBase.setId(string);
            binBase.setIda(GlobalConfig.MASTER_INN);
            binBase.setIdr(GlobalConfig.AGENT_INN);
            binBase.setState("0");
            binBases.add(binBase);
        }
        //updateSE(base, table_name, binBases);
        base.syncUpdElements(table_name, binBases, ((GlobalConfig.IS_MASTER)?true:false) );
        
    }
    
    public synchronized static void fake_delete(Base base, String table_name, String id) {
        BeanBase binBase = new BeanBase();
        binBase.setId(id);
        binBase.setIda(GlobalConfig.MASTER_INN);
        binBase.setIdr(GlobalConfig.AGENT_INN);
        binBase.setState("0");
        //update(base, table_name, binBase);
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.add(binBase);
        base.syncUpdElements(table_name, bbs, ((GlobalConfig.IS_MASTER)?true:false));
    }
    
    public synchronized static void UpdIDRElements(Base base, String baseName, String from_id, String to_id) {
        base.syncUpdIDRElements(baseName, from_id, to_id);
    }

    public synchronized static boolean grab(Base base, MulisFrame frame) {
        boolean r = false;
        BeanResult binResult = Util.getBinResult(frame);
        binResult.setIdr(((MulisComboBoxModelUsers) (frame.getAgentInfo()).getModel()).getCurrentElement(frame.getAgentInfo().getSelectedIndex()).toString());
        if (r = binResult.test(frame.getRootPane(), frame)) {
            if (!frame.isMod()) {
                boolean rx = insert(base, frame.getName(), binResult);
                if (!rx) {
                    // если id при вставке != null
                    String newId = Integer.toString(ExUtil.count(base, frame.getName(), null) + 1);
                    if (GlobalConfig.DEBUG > 0) {
                        System.out.println("\n[Set new ID: " + newId + "]");
                    }
                    frame.setID(newId);
                    binResult.setId(newId);
                    insert(base, frame.getName(), binResult);
                }
            } else {
                update(base, frame.getName(), binResult);
            }
        }
        return r;
    }
    
    public static void buildPrintTMPL(Base base, String name, String fields, String where_add, List<String> ids, int tmpl, boolean map, boolean addInfo, boolean photo, boolean contact) {
        String where="id IN(";
        for (Iterator<String> it = ids.iterator(); it.hasNext();) {
            String string = it.next();
            where+=string+(it.hasNext()?",":")");
        }
        if (ids.isEmpty()) where="";
        MulisPrinter printer = new MulisPrinter(selectSE(base, name, fields, where+((where_add.trim().isEmpty())?"":((where.isEmpty())?" ":" AND ")+where_add+" ")), name);
        printer.build(map,addInfo,photo,contact,tmpl);
    }

    /**
     * Запрос из базы всех данных и вставка их в таблицу
     * @param base
     * @param table
     * @param name
     * @param fields 
     */
    public synchronized static void fillTabelData(Base base, MulisTable table, String name, String fields, String where, boolean full) {
        // TODO: ДОДЕЛАТЬ!!!
        
        long ts = System.currentTimeMillis();
        boolean cur=false;
        if (table.getRowCount()==0) cur=true;
        int maxRow=0;
        DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
        if (!(name+where).equals(name+table.getCurWhere())) {
            maxRow = countSE(base, name, where);
            if (maxRow<GlobalConfig.FIRST_LOAD) {table.setLimit(0,GlobalConfig.FIRST_LOAD);}
            table.fixLimit(maxRow);
            tableModel.setNumRows(0);
            tableModel.getDataVector().removeAllElements();
            table.setCurWhere(where);
            cur=true;
        }
        if (full) table.setLimit(0,countSE(base, name, where));

        int i = table.getCurMin();
        if (cur) tableModel.setNumRows(maxRow);
        int maxI = tableModel.getRowCount();
        if (table.getCurMax()-GlobalConfig.ADD_LIMIT<maxI  || maxI<GlobalConfig.FIRST_LOAD || cur) 
            if (Util.pepareSelect(tableModel, i, table.getCurMax()-GlobalConfig.ADD_LIMIT))
            for (Iterator<BeanBase> it = selectSE(base, name, fields, where+table.getRowSort()+table.getLimit()).iterator(); it.hasNext();) {
                BeanBase binBase = it.next();
                int j=0;
                if (tableModel.getValueAt(i, 0)==null) {
                    tableModel.setValueAt(binBase.getId(), i, j++);
                    tableModel.setValueAt(binBase.getIda(), i, j++);
                    tableModel.setValueAt(Lang.findAgentNameByIDA(binBase.getIda(), binBase.getIdr()) , i, j++);
                    tableModel.setValueAt(binBase.getState(), i, j++);
                    tableModel.setValueAt(binBase.getDate_add(), i, j++);
                    tableModel.setValueAt(binBase.getDate_mod(), i, j++);
                    for (Iterator<BeanParam> it1 = binBase.getParams().iterator(); it1.hasNext();) {
                        BeanParam binParam1 = it1.next();
                        if (binParam1.getName().equals(GlobalConfig.COLORIZED_NAME)) tableModel.setValueAt(binParam1.getValue(), i, j++);
                        else tableModel.setValueAt(Lang.findByName(binParam1.getName(), binParam1.getValue()), i, j++);
                    }
                }
                i++;
                //tableModel.insertRow(table.getRowCount(), v);
            }
        if (cur) tableModel.setRowCount(maxRow);
        if (GlobalConfig.DEBUG > 0) {
            System.out.println("FillTable " + name + " - [OK:" + Util.getDiffTime(ts, System.currentTimeMillis()) + "]");
        }
        
            /*table.getRowSorter().addRowSorterListener(new RowSorterListener() {
                @Override
                public void sorterChanged(RowSorterEvent e) {
                    System.out.println("state changed");
                }
            });*/
    }

    /**
     * Запрос из базы только нужной строки
     * @param base
     * @param table
     * @param name
     * @param fields 
     * @param id 
     */
    public synchronized static void fillTabelData(Base base, MulisTable table, String name, String fields, String where, String id) {
        // TODO: ДОДЕЛАТЬ!!!
        long ts = System.currentTimeMillis();

        DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
        
        for (Iterator<BeanBase> it = selectSE(base, name, fields, where+" AND id="+id+" "+table.getRowSort()).iterator(); it.hasNext();) {
            BeanBase binBase = it.next();
            int j=0;
            int i=table.getSelectedRow();
            if (tableModel.getValueAt(i, 0)!=null && tableModel.getValueAt(i, 0).equals(binBase.getId())) {
                tableModel.setValueAt(binBase.getId(), i, j++);
                tableModel.setValueAt(binBase.getIda(), i, j++);
                tableModel.setValueAt(Lang.findAgentNameByIDA(binBase.getIda(), binBase.getIdr()) , i, j++);
                tableModel.setValueAt(binBase.getState(), i, j++);
                tableModel.setValueAt(binBase.getDate_add(), i, j++);
                tableModel.setValueAt(binBase.getDate_mod(), i, j++);
                for (Iterator<BeanParam> it1 = binBase.getParams().iterator(); it1.hasNext();) {
                    BeanParam binParam1 = it1.next();
                    if (binParam1.getName().equals(GlobalConfig.COLORIZED_NAME)) tableModel.setValueAt(binParam1.getValue(), i, j++);
                    else tableModel.setValueAt(Lang.findByName(binParam1.getName(), binParam1.getValue()), i, j++);
                }
            }
        }
        if (GlobalConfig.DEBUG > 0) {
            System.out.println("FillTable["+id+"] " + name + " - [OK:" + Util.getDiffTime(ts, System.currentTimeMillis()) + "]");
        }
    }
    
    public synchronized static void initTable(Base base, String name, String fields) {
        base.init(name, fields);
    }

    public synchronized static boolean insert(Base base, String base_name, BeanResult result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        //for (int i = 0; i < 10000; i++) {
            bbs.add(result);
        //}
        return base.syncAddElements(base_name, bbs);
    }

    public synchronized static boolean insert(Base base, String base_name, List<BeanResult> result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.addAll(result);
        return base.syncAddElements(base_name, bbs);
    }
    
    public synchronized static boolean insertSE(Base base, String base_name, List<BeanBase> result) {
        return base.syncAddElements(base_name, result);
    }
    
    public synchronized static boolean delete(Base base, String base_name, BeanResult result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.add(result);
        return base.syncDelElements(base_name, bbs);
    }

    public synchronized static boolean delete(Base base, String base_name, List<BeanResult> result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.addAll(result);
        return base.syncDelElements(base_name, bbs);
    }
    
    public synchronized static boolean deleteSE(Base base, String base_name, List<BeanBase> result) {
        return base.syncDelElements(base_name, result);
    }
    
    public synchronized static boolean update(Base base, String base_name, BeanBase binBase) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.add(binBase);
        return base.syncUpdElements(base_name, bbs);
    }
    
    public synchronized static boolean updateSE(Base base, String base_name, List<BeanBase> binBases) {
        return base.syncUpdElements(base_name, binBases);
    }
    
    public synchronized static boolean update(Base base, String base_name, BeanResult result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.add(result);
        return base.syncUpdElements(base_name, bbs);
    }

    public synchronized static boolean update(Base base, String base_name, List<BeanResult> result) {
        List<BeanBase> bbs = new ArrayList<BeanBase>();
        bbs.addAll(result);
        return base.syncUpdElements(base_name, bbs);
    }

    public synchronized static int count(Base base, String base_name, String status) {
        return base.syncCountElements(base_name, status);
    }
    
    public synchronized static int countSE(Base base, String base_name, String where) {
        return base.syncCountElementsSE(base_name, where);
    }
}